package org.springblade.modules.repair.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springblade.common.constant.TemplateMsgConstant;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.modules.repair.dto.PlanLogDTO;
import org.springblade.modules.repair.dto.SimpleElevatorPlanInfoDTO;
import org.springblade.modules.repair.entity.*;
import org.springblade.modules.repair.enums.ElevatorUseTypeEnum;
import org.springblade.modules.repair.enums.MaintainPlanContentEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.enums.WorkTrackStatusEnum;
import org.springblade.modules.repair.mapper.MaintainSigntureMapper;
import org.springblade.modules.repair.service.*;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.SimpleUserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class MaintainSigntureServiceImpl extends BaseServiceImpl<MaintainSigntureMapper, MaintainSignture> implements MaintainSigntureService {

	@Autowired
	private MaintainPlanSpecialConfigService specialConfigService;
	@Autowired
	private IMaintainPlanContentService planContentService;
	@Autowired
	private MaintainZsTemplateService zsTemplateService;
	@Autowired
	private IMaintainMalfunctionLogService malfunctionLogService;
	@Autowired
	private IMaintainPlanContentUserService planContentUserService;
	@Autowired
	private IUserService userService;
	@Autowired
	private IMaintainSignService signService;
	@Autowired
	private IMaintainPlanContentExtService planContentExtService;
	@Autowired
	private ElevatorPlanStrategyService elevatorPlanStrategyService;

	@Value("${project.api.url.estate}")
	private String estateApiUrl;
	@Value("${project.api.url.web}")
	private String maintainApiUrl;

	private final String note_push_url = "/tlw/alarm/note/push";
	private final String official_accounts_push_url = "/tlw/alarm/official/accounts/push";
	private final String estate_sms_code = "twy_estate_sign_push";

	@Override
	@Transactional(rollbackFor = Exception.class)
	public synchronized Boolean signature(MaintainSignture signature) {

		User user = userService.getById(signature.getUserId());

		int userSign = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getUserId,signature.getUserId()).eq(MaintainSign::getPlanId,signature.getPlanId()));
		if(userSign <= 0){
			throw new ServiceException("未参与工作无需签字");
		}

		int count = super.count(Wrappers.<MaintainSignture>lambdaQuery().eq(MaintainSignture::getPlanId,signature.getPlanId()).eq(MaintainSignture::getUserId,signature.getUserId()));
		if(count > 0){
			throw new ServiceException("请勿重复签字");
		}
		super.save(signature);

		// 插入任务记录
		PlanLogDTO planLogDTO = new PlanLogDTO();
		planLogDTO.setSignatureId(signature.getId());
		planLogDTO.setImage(signature.getSignImg());
		malfunctionLogService.insertWorkLog(signature.getPlanId(), WorkTrackStatusEnum.SIGNATURE.getTypeName(),TaskStatusEnum.BY_FINISH.getStatus(), JSONObject.toJSONString(planLogDTO), AuthUtil.getUserId(),user.getRealName());


		int signCount = signService.count(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId,signature.getPlanId()).ne(MaintainSign::getUserId,signature.getUserId()));
		if(signCount > 0){
			int signatureCount = super.count(Wrappers.<MaintainSignture>lambdaQuery().eq(MaintainSignture::getPlanId,signature.getPlanId()));
			List<MaintainSign> userSignList = signService.list(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId,signature.getPlanId()));
			userSignList = userSignList.stream().collect(Collectors.collectingAndThen(
				Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MaintainSign::getUserId))), ArrayList::new
			));
			if(signatureCount != userSignList.size()){
				return Boolean.TRUE;
			}
		}

		// 更改工单状态
		MaintainPlanContent planContent = planContentService.getById(signature.getPlanId());
		planContent.setStatus(TaskStatusEnum.BY_MAINTAIN_SIGN.getStatus());
		planContentService.update(planContent);

		ElevatorPlanStrategy elevatorPlanStrategy = elevatorPlanStrategyService.getOne(Wrappers.<ElevatorPlanStrategy>lambdaQuery().eq(ElevatorPlanStrategy::getElevatorId,planContent.getElevatorId()));
		MaintainPlanContentExt planContentExt = planContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId,signature.getPlanId()));
		planContentExt.setMaintainSignatureTime(DateUtil.date());
		if(ObjectUtil.isNotEmpty(elevatorPlanStrategy)){
			planContentExt.setOverdueDate(elevatorPlanStrategy.getOverdueDate());
		}

		if(Func.isNotEmpty(elevatorPlanStrategy.getOverdueDate())){
			Date today = DateUtil.parseDate(DateUtil.today());
			// 未逾期
			if(today.getTime() <= elevatorPlanStrategy.getOverdueDate().getTime()){
				planContentExt.setOverdueType(1);
			}
			// 已逾期
			if(today.getTime() > elevatorPlanStrategy.getOverdueDate().getTime()){
				planContentExt.setOverdueType(3);
			}
		}
		planContentExtService.updateById(planContentExt);

		// 插入任务记录
		malfunctionLogService.insertWorkLog(signature.getPlanId(), WorkTrackStatusEnum.MAINTAIN_SIGNATURE.getTypeName(),TaskStatusEnum.BY_MAINTAIN_SIGN.getStatus());

		// 发送物业端消息
		planContentService.sendEstateMsg(signature.getPlanId());

//		if(signCount <= 0){
//			// 单人完成作业时直接发送消息
//
//		}else {
//			int signatureCount = super.count(Wrappers.<MaintainSignture>lambdaQuery().eq(MaintainSignture::getPlanId,signature.getPlanId()));
//			List<MaintainSign> userSignList = signService.list(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId,signature.getPlanId()));
//			userSignList = userSignList.stream().collect(Collectors.collectingAndThen(
//				Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MaintainSign::getUserId))), ArrayList::new
//			));
//			if(signatureCount == userSignList.size()){
//				// 所有签到人签字后发送消息
//
//			}
//		}
		return Boolean.TRUE;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean signatureEstate(MaintainSignture signature) {

		MaintainPlanContent planContent = planContentService.getById(signature.getPlanId());
		if(!planContent.getStatus().equals(TaskStatusEnum.BY_MAINTAIN_SIGN.getStatus())){
			throw new ServiceException("客户已签字完成");
		}

		super.save(signature);

		// 插入任务记录
		PlanLogDTO planLogDTO = new PlanLogDTO();
		planLogDTO.setSignatureId(signature.getId());
		planLogDTO.setImage(signature.getSignImg());
		malfunctionLogService.insertWorkLog(signature.getPlanId(), WorkTrackStatusEnum.ESTATE_SIGNATURE.getTypeName(),TaskStatusEnum.BY_SIGN.getStatus(), JSONObject.toJSONString(planLogDTO), AuthUtil.getUserId(),WorkTrackStatusEnum.ESTATE_SIGNATURE.getTypeName());

		// 所有签到人签字后更改任务状态为完成
		planContent.setStatus(TaskStatusEnum.BY_SIGN.getStatus());
		planContent.setId(signature.getPlanId());
		planContentService.update(planContent);

		// 分割日志时间
//		ThreadUtil.safeSleep(500);
		// 插入任务记录
		malfunctionLogService.insertWorkLog(signature.getPlanId(), WorkTrackStatusEnum.FINISHED.getTypeName(),TaskStatusEnum.BY_SIGN.getStatus());

		return Boolean.TRUE;
	}

	@Override
	public HashMap<String, Object> signatureEstateStatus(Long planId) {
		HashMap<String,Object> resultMap = new HashMap<>(2);
		resultMap.put("result",Boolean.TRUE);
		resultMap.put("userList",new ArrayList<>());

		int signatureCount = super.count(Wrappers.<MaintainSignture>lambdaQuery().eq(MaintainSignture::getPlanId,planId).isNotNull(MaintainSignture::getUserId));
		List<MaintainSign> userSignList = signService.list(Wrappers.<MaintainSign>lambdaQuery().eq(MaintainSign::getPlanId,planId));
		userSignList = userSignList.stream().collect(Collectors.collectingAndThen(
			Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(MaintainSign::getUserId))), ArrayList::new
		));
		if(signatureCount != userSignList.size()){
			List<Long> userSignIds = userSignList.stream().map(MaintainSign::getUserId).collect(Collectors.toList());
			List<Long> userSignatureIds = super.list(Wrappers.<MaintainSignture>lambdaQuery().eq(MaintainSignture::getPlanId,planId).isNotNull(MaintainSignture::getUserId)).stream().map(MaintainSignture::getUserId).collect(Collectors.toList());
			List<Long> userIds = userSignIds.stream().filter(item -> !userSignatureIds.contains(item)).collect(Collectors.toList());
			List<User> users = userService.listByIds(userIds);
			resultMap.put("result",Boolean.FALSE);
			resultMap.put("userList",users);
		}
		return resultMap;
	}

}

